package org.linlinjava.litemall.db.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import org.linlinjava.litemall.db.dao.LitemallGoodsMapper;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.domain.LitemallGoods.Column;
import org.linlinjava.litemall.db.util.DateUtil;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class GoodsService {
    Column[] columns = new Column[]{Column.id, Column.goodsSn, Column.initialNumber, Column.killNumber,
            Column.number, Column.name, Column.categoryId, Column.recommend, Column.gallery, Column.keywords,
            Column.brief, Column.isOnSale, Column.sortOrder, Column.picUrl, Column.counterPrice, Column.killPrice, Column.retailPrice,
            Column.detail, Column.startTime, Column.endTime, Column.addTime};
    @Resource
    private LitemallGoodsMapper goodsMapper;

    @Resource
    private FootprintService footprintService;

    /**
     * 获取新品上市
     *
     * @param offset
     * @param limit
     * @return
     */
    public List<LitemallGoods> queryByNew(Integer userId, int offset, int limit) {
        PageHelper.clearPage();
        Integer category = footprintService.queryByLimitCategory(userId);
        LitemallGoodsExample example = new LitemallGoodsExample();
        LitemallGoodsExample.Criteria criteria = example.createCriteria();
        if (!Objects.isNull(category)) {
            criteria.andCategoryIdEqualTo(category);
        }


        example.or().andIsOnSaleEqualTo(true).andDeletedEqualTo(false);
        example.setOrderByClause("add_time desc");
        PageHelper.startPage(offset, limit);
        return goodsMapper.selectByExampleSelective(example, columns);
    }

    /**
     * 获取分类下的商品
     *
     * @param catList
     * @param offset
     * @param limit
     * @return
     */
    public List<LitemallGoods> queryByCategory(List<Integer> catList, int offset, int limit) {
        LitemallGoodsExample example = new LitemallGoodsExample();
        example.or().andCategoryIdIn(catList).andIsOnSaleEqualTo(true).andDeletedEqualTo(false);
        example.setOrderByClause("add_time  desc");
        PageHelper.startPage(offset, limit);

        return goodsMapper.selectByExampleSelective(example, columns);
    }


    /**
     * 获取分类下的商品
     *
     * @param catId
     * @param offset
     * @param limit
     * @return
     */
    public List<LitemallGoods> queryByCategory(Integer catId, int offset, int limit) {
        LitemallGoodsExample example = new LitemallGoodsExample();
        example.or().andCategoryIdEqualTo(catId).andIsOnSaleEqualTo(true).andDeletedEqualTo(false);
        example.setOrderByClause("add_time desc");
        PageHelper.startPage(offset, limit);

        return goodsMapper.selectByExampleSelective(example, columns);
    }


    public List<LitemallGoods> querySelective(Integer userId, Integer catId, String keywords, Integer offset, Integer limit, String sort, String order) {
        LitemallGoodsExample example = new LitemallGoodsExample();
        LitemallGoodsExample.Criteria criteria1 = example.or();
        LitemallGoodsExample.Criteria criteria2 = example.or();

        PageHelper.startPage(offset, limit);
        if (!StringUtils.isEmpty(catId) && catId != 0) {
            if (1 == catId) {
                return this.queryByNew(userId, offset, limit);
            }
            criteria1.andCategoryIdEqualTo(catId);
            criteria2.andCategoryIdEqualTo(catId);
        }
        if (!StringUtils.isEmpty(keywords)) {
            criteria1.andKeywordsLike("%" + keywords + "%");
            criteria2.andNameLike("%" + keywords + "%");
        }
        criteria1.andIsOnSaleEqualTo(true);
        criteria2.andIsOnSaleEqualTo(true);
        criteria1.andDeletedEqualTo(false);
        criteria2.andDeletedEqualTo(false);

        if (!StringUtils.isEmpty(sort) && !StringUtils.isEmpty(order)) {
            example.setOrderByClause(sort + " " + order);
        }

        return goodsMapper.selectByExampleSelective(example, columns);
    }

    public List<LitemallGoods> querySelective(Integer goodsId, String goodsSn, String name, Integer page, Integer size, String sort, String order) {
        LitemallGoodsExample example = new LitemallGoodsExample();
        LitemallGoodsExample.Criteria criteria = example.createCriteria();

        if (goodsId != null) {
            criteria.andIdEqualTo(goodsId);
        }
        if (!StringUtils.isEmpty(goodsSn)) {
            criteria.andGoodsSnEqualTo(goodsSn);
        }
        if (!StringUtils.isEmpty(name)) {
            criteria.andNameLike("%" + name + "%");
        }
        criteria.andDeletedEqualTo(false);

        if (!StringUtils.isEmpty(sort) && !StringUtils.isEmpty(order)) {
            example.setOrderByClause(sort + " " + order);
        }

        PageHelper.startPage(page, size);
        return goodsMapper.selectByExampleWithBLOBs(example);
    }

    /**
     * 获取某个商品信息,包含完整信息
     *
     * @param id
     * @return
     */
    public LitemallGoods findById(Integer id) {
        LitemallGoodsExample example = new LitemallGoodsExample();
        example.or().andIdEqualTo(id).andDeletedEqualTo(false);
        return goodsMapper.selectOneByExampleWithBLOBs(example);
    }

    /**
     * 获取某个商品信息，仅展示相关内容
     *
     * @param id
     * @return
     */
    public LitemallGoods findByIdVO(Integer id) {
        LitemallGoodsExample example = new LitemallGoodsExample();
        example.or().andIdEqualTo(id).andIsOnSaleEqualTo(true).andDeletedEqualTo(false);
        return goodsMapper.selectOneByExampleSelective(example, columns);
    }


    /**
     * 获取所有在售物品总数
     *
     * @return
     */
    public Integer queryOnSale() {
        LitemallGoodsExample example = new LitemallGoodsExample();
        example.or().andIsOnSaleEqualTo(true).andDeletedEqualTo(false);
        return (int) goodsMapper.countByExample(example);
    }

    public int updateById(LitemallGoods goods) {
        goods.setUpdateTime(LocalDateTime.now());
        return goodsMapper.updateByPrimaryKeySelective(goods);
    }

    public void deleteById(Integer id) {
        goodsMapper.logicalDeleteByPrimaryKey(id);
    }

    public void add(LitemallGoods goods) {
        goods.setAddTime(LocalDateTime.now());
        goods.setUpdateTime(LocalDateTime.now());
        goodsMapper.insertSelective(goods);
    }

    /**
     * 获取所有物品总数，包括在售的和下架的，但是不包括已删除的商品
     *
     * @return
     */
    public int count() {
        LitemallGoodsExample example = new LitemallGoodsExample();
        example.or().andDeletedEqualTo(false);
        return (int) goodsMapper.countByExample(example);
    }

    public List<Integer> getCatIds(String keywords) {
        LitemallGoodsExample example = new LitemallGoodsExample();
        LitemallGoodsExample.Criteria criteria1 = example.or();
        LitemallGoodsExample.Criteria criteria2 = example.or();

        if (!StringUtils.isEmpty(keywords)) {
            criteria1.andKeywordsLike("%" + keywords + "%");
            criteria2.andNameLike("%" + keywords + "%");
        }
        criteria1.andIsOnSaleEqualTo(true);
        criteria2.andIsOnSaleEqualTo(true);
        criteria1.andDeletedEqualTo(false);
        criteria2.andDeletedEqualTo(false);

        List<LitemallGoods> goodsList = goodsMapper.selectByExampleSelective(example, Column.categoryId);
        List<Integer> cats = new ArrayList<Integer>();
        for (LitemallGoods goods : goodsList) {
            cats.add(goods.getCategoryId());
        }
        return cats;
    }

    public boolean checkExistByName(String name) {
        LitemallGoodsExample example = new LitemallGoodsExample();
        example.or().andNameEqualTo(name).andIsOnSaleEqualTo(true).andDeletedEqualTo(false);
        return goodsMapper.countByExample(example) != 0;
    }

    public List<LitemallGoods> queryByIds(Integer[] ids) {
        LitemallGoodsExample example = new LitemallGoodsExample();
        example.or().andIdIn(Arrays.asList(ids)).andIsOnSaleEqualTo(true).andDeletedEqualTo(false);
        return goodsMapper.selectByExampleSelective(example, columns);
    }

    public int addStock(Integer goodsId, Short number) {
        return goodsMapper.addStock(goodsId, number);
    }

    public int addKillStock(Integer goodsId, Short number) {
        return goodsMapper.addKillStock(goodsId, number);
    }

    public int reduceStock(Integer id, Short number) {
        return goodsMapper.reduceStock(id, number);
    }

    public int reduceKillStock(Integer id, Short number) {
        return goodsMapper.reduceKillStock(id, number);
    }


    public Map<String, List<LitemallGoods>> secKillAll() {
        // 获取开始时间是今日的
        List<LitemallGoods> secKills = goodsMapper.selectList(Wrappers.<LitemallGoods>lambdaQuery()
                .le(LitemallGoods::getStartTime, DateUtil.currentTime())
                .ge(LitemallGoods::getEndTime, DateUtil.currentTime()));
        return secKills.stream().collect(Collectors.groupingBy(s -> s.getStartTime() + "_" + s.getEndTime(), Collectors.toList()));
    }

//    public Map<String, List<LitemallGoods>> secKillAll() {
//        // 获取开始时间是今日的
//        List<LitemallGoods> secKills = goodsMapper.selectList(Wrappers.<LitemallGoods>lambdaQuery()
//                .le(LitemallGoods::getStartTime, DateUtil.tomorrow())
//                .ge(LitemallGoods::getEndTime, DateUtil.yesterday()));
//        return secKills.stream().collect(Collectors.groupingBy(s -> s.getStartTime() + "_" + s.getEndTime(), Collectors.toList()));
//    }

    public List<LitemallGoods> secKillNew() {
        // 获取开始时间是今日的
        List<LitemallGoods> secKills = goodsMapper.selectList(Wrappers.<LitemallGoods>lambdaQuery()
                .le(LitemallGoods::getStartTime, DateUtil.currentTime())
                .ge(LitemallGoods::getEndTime, DateUtil.currentTime()));
        if (secKills.isEmpty()){
            return new ArrayList<>();
        }
        Map<String, List<LitemallGoods>> collect = secKills.stream().collect(Collectors.groupingBy(s -> s.getStartTime() + "_" + s.getEndTime(), Collectors.toList()));
        // 获取最新时间数据
        return collect.get(Collections.min(collect.keySet()));
    }

    public List<LitemallGoods> queryKillList(Integer page, Integer limit) {
        PageHelper.startPage(page, limit);
        QueryWrapper<LitemallGoods> objectQueryWrapper = new QueryWrapper<>();
        objectQueryWrapper.isNotNull("kill_price");
        objectQueryWrapper.orderByDesc("sort_order");
        return goodsMapper.selectList(objectQueryWrapper);
    }

    public void deleteKillById(Integer id) {
        goodsMapper.deleteKillById(id);
    }

    public LitemallGoods findByGoodIdBetween(Integer goodsId, String date) {
        return goodsMapper.selectOne(Wrappers.<LitemallGoods>lambdaQuery()
                .eq(LitemallGoods::getId, goodsId)
                .gt(LitemallGoods::getEndTime, date)
                .le(LitemallGoods::getStartTime, date));
    }

    public LitemallGoods findByGoodGe(Integer goodsId) {
        QueryWrapper<LitemallGoods> objectQueryWrapper = new QueryWrapper<>();
        objectQueryWrapper.eq("id", goodsId);
        objectQueryWrapper.ge("start_time", DateUtil.currentTime());
        return goodsMapper.selectOne(objectQueryWrapper);
    }

}
